home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / tests / pdevtest / printStats.c < prev    next >
C/C++ Source or Header  |  1989-10-23  |  23KB  |  645 lines

  1. /*
  2.  * printStats.c --
  3.  *    Routines to print out program execution times, and filesystem stats.
  4.  */
  5.  
  6. #include <sprite.h>
  7. #include <status.h>
  8. #include <stdio.h>
  9. #include <proc.h>
  10. #include <vm.h>
  11. #include <kernel/fs.h>
  12. #include <kernel/fsStat.h>
  13. #include <kernel/sched.h>
  14. #include <kernel/vm.h>
  15.  
  16.  
  17.  
  18. /*
  19.  *----------------------------------------------------------------------
  20.  *
  21.  * PrintTimes --
  22.  *
  23.  *    Print the resource usage (user and kernel CPU time) and elapsed time.
  24.  *
  25.  * Results:
  26.  *    None.
  27.  *
  28.  * Side effects:
  29.  *    Prints to the specified stream
  30.  *
  31.  *----------------------------------------------------------------------
  32.  */
  33. void
  34. PrintTimes(stream, usagePtr, timePtr)
  35.     FILE *stream;
  36.     Proc_ResUsage *usagePtr;
  37.     Time *timePtr;
  38. {
  39.     Time delta;
  40.     if (usagePtr != NULL) {
  41.     Time_Add(usagePtr->userCpuUsage, usagePtr->childUserCpuUsage,
  42.                      &delta);
  43.     fprintf(stream, "%d.%03du ", delta.seconds,
  44.                    delta.microseconds / 1000);
  45.     Time_Add(usagePtr->kernelCpuUsage, usagePtr->childKernelCpuUsage,
  46.                      &delta);
  47.     fprintf(stream, "%d.%03ds ", delta.seconds,
  48.                    delta.microseconds / 1000);
  49.     }
  50.     if (timePtr != NULL) {
  51.     int seconds = timePtr->seconds;
  52.     if (seconds >= 3600) {
  53.         fprintf(stream, "%d:", seconds / 3600);
  54.         seconds = seconds % 3600;
  55.     }
  56.     if (seconds >= 60) {
  57.         fprintf(stream, "%d:", seconds / 60);
  58.         seconds = seconds % 60;
  59.     }
  60.     fprintf(stream, "%d.%03d", seconds,
  61.                    timePtr->microseconds / 1000);
  62.     }
  63.     fprintf(stream, "\n");
  64. }
  65.  
  66.  
  67. /*
  68.  *----------------------------------------------------------------------
  69.  *
  70.  * PrintIdleTime --
  71.  *
  72.  *    Given two samples sched module statistics, this computes
  73.  *    the differenc in idle ticks and, using the time, computes
  74.  *    a utilization.
  75.  *
  76.  * Results:
  77.  *    None.
  78.  *
  79.  * Side effects:
  80.  *    Prints to the specified stream
  81.  *
  82.  *----------------------------------------------------------------------
  83.  */
  84. void
  85. PrintIdleTime(stream, startSchedPtr, endSchedPtr, timePtr)
  86.     FILE *stream;
  87.     Sched_Instrument *startSchedPtr, *endSchedPtr;
  88.     Time *timePtr;
  89. {
  90.     register     highTicks;
  91.     double     lowTicks;
  92.  
  93.     Sched_Instrument zeroStats;
  94.     if (startSchedPtr == NULL) {
  95.     bzero(&zeroStats, sizeof(Sched_Instrument));
  96.     startSchedPtr = &zeroStats;
  97.     }
  98.     highTicks = endSchedPtr->processor[0].idleTicksOverflow -
  99.         startSchedPtr->processor[0].idleTicksOverflow;
  100.     lowTicks = endSchedPtr->processor[0].idleTicksLow -
  101.     startSchedPtr->processor[0].idleTicksLow;
  102.  
  103.     if (highTicks != 0) {
  104.     fprintf(stream, "(High ticks = %d)", highTicks);
  105.     }
  106.     if (timePtr->seconds == 0 && timePtr->microseconds == 0) {
  107.     fprintf(stream, "Idle ticks --/-- = 100%% Idle, Elapsed time ");
  108.     } else {
  109.     lowTicks /= 
  110.       (double)timePtr->seconds + (double) (timePtr->microseconds)*1000000.;
  111.     fprintf(stream, "Idle ticks %0.0f/%d = %6.2f%% Idle, Context Sw. %d inv %d full %d, Elapsed time ",
  112.            lowTicks,
  113.            endSchedPtr->processor[0].idleTicksPerSecond,
  114.            (double)lowTicks/
  115.            (double)endSchedPtr->processor[0].idleTicksPerSecond * 100.,
  116.            endSchedPtr->processor[0].numContextSwitches -
  117.            startSchedPtr->processor[0].numContextSwitches,
  118.            endSchedPtr->processor[0].numInvoluntarySwitches -
  119.            startSchedPtr->processor[0].numInvoluntarySwitches,
  120.            endSchedPtr->processor[0].numFullCS -
  121.            startSchedPtr->processor[0].numFullCS);
  122.     }
  123.     PrintTimes(stream, (Proc_ResUsage *)0, timePtr);
  124. }
  125.  
  126.  
  127. /*
  128.  *----------------------------------------------------------------------
  129.  *
  130.  * PrintFs_Stats --
  131.  *
  132.  *    Print out the filesystem statistics.  If both a start and end
  133.  *    sample of the statistics are given then the differences between
  134.  *    the two are printed.  To just print the total cumulative statistics
  135.  *    from one sample, specify a single Fs_Stats buffer with the 'end'
  136.  *    parameter.
  137.  *
  138.  * Results:
  139.  *    None.
  140.  *
  141.  * Side effects:
  142.  *    Prints to the specified stream
  143.  *
  144.  *----------------------------------------------------------------------
  145.  */
  146. void
  147. PrintFs_Stats(stream, start, end, verbose)
  148.     FILE *stream;    /* Output stream */
  149.     Fs_Stats *start;    /* 0, or address of "before run" statistics */
  150.     Fs_Stats *end;    /* End of run statistics */
  151.     int verbose;    /* If true, everything is dumped */
  152. {
  153.     register int t1, t2, t3, t4, t5;
  154.     Fs_Stats zeroStats;
  155.  
  156.     if (start == (Fs_Stats *)0) {
  157.     bzero(&zeroStats, sizeof(Fs_Stats));
  158.     start = &zeroStats;
  159.     }
  160.     /*
  161.      * Print cache size
  162.      */
  163.     fprintf(stream, "Cache blocks max %d min %d number %d/%d free %d/%d limit %d\n",
  164.                end->blockCache.maxCacheBlocks,
  165.                end->blockCache.minCacheBlocks,
  166.                start->blockCache.numCacheBlocks,
  167.                end->blockCache.numCacheBlocks,
  168.                start->blockCache.numFreeBlocks,
  169.                end->blockCache.numFreeBlocks,
  170.                end->blockCache.maxNumBlocks);
  171.  
  172.     /*
  173.      * Print bytes read traffic ratio
  174.      */
  175.     t1 = end->blockCache.bytesRead - start->blockCache.bytesRead;
  176.     t2 = end->blockCache.dirBytesRead - start->blockCache.dirBytesRead;
  177.     t3 = end->gen.remoteBytesRead - start->gen.remoteBytesRead;
  178.     t4 = end->gen.fileBytesRead - start->gen.fileBytesRead;
  179.     t5 = end->gen.physBytesRead - start->gen.physBytesRead;
  180.     fprintf(stream, "Bytes read %d+%d remote %d disk %d+%d",
  181.                t1, t2, t3, t4, t5);
  182.     if (t1 + t2 > 0) {
  183.     fprintf(stream, "\ttraffic ratio %%%d\n",
  184.                (int)((double)(t3+t4+t5)/(double)(t1+t2) * 100.));
  185.     } else {
  186.     fprintf(stream, "\n");
  187.     }
  188.  
  189.     /*
  190.      * Print bytes written traffic ratio
  191.      */
  192.     t1 = end->blockCache.bytesWritten - start->blockCache.bytesWritten +
  193.     (end->blockCache.fileDescWrites - start->blockCache.fileDescWrites +
  194.      end->blockCache.indBlockWrites - start->blockCache.indBlockWrites) *
  195.     FS_BLOCK_SIZE;
  196.     t2 = end->blockCache.dirBytesWritten - start->blockCache.dirBytesWritten;
  197.     t3 = end->gen.remoteBytesWritten - start->gen.remoteBytesWritten;
  198.     t4 = end->gen.fileBytesWritten - start->gen.fileBytesWritten;
  199.     t5 = end->gen.physBytesWritten - start->gen.physBytesWritten;
  200.     fprintf(stream, "Bytes written %d+%d remote %d disk %d+%d",
  201.                t1, t2, t3, t4, t5);
  202.     if (t1 + t2 > 0) {
  203.     fprintf(stream, "\ttraffic ratio %%%d",
  204.                (int)((double)(t3+t4+t5)/(double)(t1+t2) * 100.));
  205.     }
  206.     fprintf(stream, "\n");
  207.  
  208.     if (verbose) {
  209.     /*
  210.      * Print device bytes and zero fills
  211.      */
  212.     t1 = end->gen.deviceBytesWritten - start->gen.deviceBytesWritten;
  213.     t2 = end->gen.deviceBytesRead - start->gen.deviceBytesRead;
  214.     fprintf(stream, "Dev bytes read %d written %d\n", t1, t2);
  215.     t1 = end->blockCache.readZeroFills - start->blockCache.readZeroFills;
  216.     t2 = end->blockCache.writeZeroFills1 -
  217.         start->blockCache.writeZeroFills1;
  218.     t3 = end->blockCache.writeZeroFills2 -
  219.         start->blockCache.writeZeroFills2;
  220.     t4 = end->blockCache.fragZeroFills - start->blockCache.fragZeroFills;
  221.     fprintf(stream, "Zero Fills read %d write1 %d write2 %d frag %d\n",
  222.                    t1, t2, t3, t4);
  223.     t1 = end->blockCache.appendWrites - start->blockCache.appendWrites;
  224.     t2 = end->blockCache.overWrites - start->blockCache.overWrites;
  225.     t3 = end->blockCache.domainReadFails -
  226.         start->blockCache.domainReadFails;
  227.     fprintf(stream, "Appends %d Overwrites %d Failed Reads %d\n",
  228.                    t1, t2, t3);
  229.     }
  230.     t1 = end->blockCache.readAccesses - start->blockCache.readAccesses +
  231.      end->blockCache.fragAccesses - start->blockCache.fragAccesses +
  232.      end->blockCache.fileDescReads - start->blockCache.fileDescReads +
  233.      end->blockCache.indBlockAccesses - start->blockCache.indBlockAccesses +
  234.      end->blockCache.dirBlockAccesses - start->blockCache.dirBlockAccesses;
  235.     t2 = end->blockCache.readHitsOnDirtyBlock -
  236.     start->blockCache.readHitsOnDirtyBlock;
  237.     t3 = end->blockCache.readHitsOnCleanBlock -
  238.     start->blockCache.readHitsOnCleanBlock;
  239.     t4 = end->blockCache.fragHits - start->blockCache.fragHits +
  240.      end->blockCache.fileDescReadHits - start->blockCache.fileDescReadHits +
  241.      end->blockCache.indBlockHits - start->blockCache.indBlockHits +
  242.      end->blockCache.dirBlockHits - start->blockCache.dirBlockHits;
  243.     fprintf(stream, "Cache reads %d hits: dirty %d clean %d other %d",
  244.                t1, t2, t3, t4);
  245.     if (t1 != 0) {
  246.     fprintf(stream, "\thit ratio %%%d",
  247.                (int)((double)(t2+t3+t4)/(double)t1 * 100.));
  248.     }
  249.     fprintf(stream, "\n");
  250.  
  251.     t1 = end->blockCache.readAheads - start->blockCache.readAheads;
  252.     t2 = end->blockCache.readAheadHits - start->blockCache.readAheadHits;
  253.     t3 = end->blockCache.allInCacheCalls - start->blockCache.allInCacheCalls;
  254.     t4 = end->blockCache.allInCacheTrue - start->blockCache.allInCacheTrue;
  255.     if (t1 > 0) {
  256.     fprintf(stream, "Read Ahead: hits %d/%d all-in-cache %d/%d\n",
  257.             t2, t1, t4, t3);
  258.     }
  259.  
  260.     t1 = end->blockCache.writeAccesses - start->blockCache.writeAccesses +
  261.      end->blockCache.fileDescWrites - start->blockCache.fileDescWrites +
  262.      end->blockCache.indBlockWrites - start->blockCache.indBlockWrites +
  263.      end->blockCache.dirBlockWrites - start->blockCache.dirBlockWrites;
  264.     t2 = end->blockCache.partialWriteHits - start->blockCache.partialWriteHits +
  265.     end->blockCache.fileDescWriteHits - start->blockCache.fileDescWriteHits;
  266.     t3 = end->blockCache.partialWriteMisses -
  267.     start->blockCache.partialWriteMisses;
  268.     t4 = end->blockCache.blocksWrittenThru -
  269.     start->blockCache.blocksWrittenThru;
  270.     fprintf(stream, "Cache writes %d hits %d misses %d thru %d",
  271.                t1, t2, t3, t4);
  272.     if (t1 != 0) {
  273.     fprintf(stream, "\ttraffic ratio %%%d",
  274.                (int)((double)(t3+t4)/(double)t1 * 100.));
  275.     }
  276.     fprintf(stream, "\n");
  277.     
  278.     fprintf(stream, "Write thru %d data %d indirect %d desc %d dir %d\n",
  279.                t4,
  280.                end->blockCache.dataBlocksWrittenThru -
  281.                start->blockCache.dataBlocksWrittenThru,
  282.                end->blockCache.indBlocksWrittenThru -
  283.                start->blockCache.indBlocksWrittenThru,
  284.                end->blockCache.descBlocksWrittenThru -
  285.                start->blockCache.descBlocksWrittenThru,
  286.                end->blockCache.dirBlocksWrittenThru -
  287.                start->blockCache.dirBlocksWrittenThru);
  288.     if (end->blockCache.fileDescReads > 0) {
  289.     fprintf(stream, "File descriptor reads %d hits %d writes %d hits %d\n",
  290.                    end->blockCache.fileDescReads -
  291.                    start->blockCache.fileDescReads,
  292.                    end->blockCache.fileDescReadHits -
  293.                    start->blockCache.fileDescReadHits,
  294.                    end->blockCache.fileDescWrites -
  295.                    start->blockCache.fileDescWrites,
  296.                    end->blockCache.fileDescWriteHits -
  297.                    start->blockCache.fileDescWriteHits);
  298.     }
  299.     if (end->blockCache.indBlockAccesses > 0) {
  300.     fprintf(stream, "Indirect block reads %d hits %d writes %d\n",
  301.                end->blockCache.indBlockAccesses -
  302.                start->blockCache.indBlockAccesses,
  303.                end->blockCache.indBlockHits -
  304.                start->blockCache.indBlockHits,
  305.                end->blockCache.indBlockWrites -
  306.                start->blockCache.indBlockWrites);
  307.     }
  308.     if (end->blockCache.dirBlockAccesses > 0) {
  309.     fprintf(stream, "Directory block reads %d hits %d writes %d\n",
  310.                    end->blockCache.dirBlockAccesses -
  311.                    start->blockCache.dirBlockAccesses,
  312.                    end->blockCache.dirBlockHits -
  313.                    start->blockCache.dirBlockHits,
  314.                    end->blockCache.dirBlockWrites -
  315.                    start->blockCache.dirBlockWrites);
  316.     }
  317.     if (end->blockCache.vmRequests > 0) {
  318.     fprintf(stream, "VM requests %d tried %d gave %d\n",
  319.                    end->blockCache.vmRequests -
  320.                    start->blockCache.vmRequests,
  321.                    end->blockCache.triedToGiveToVM -
  322.                    start->blockCache.triedToGiveToVM,
  323.                    end->blockCache.vmGotPage -
  324.                    start->blockCache.vmGotPage);
  325.     }
  326.     fprintf(stream, "Cache blocks created %d, alloc from free %d part %d lru %d\n",
  327.                    end->blockCache.unmapped -
  328.                    start->blockCache.unmapped,
  329.                    end->blockCache.totFree -
  330.                    start->blockCache.totFree,
  331.                    end->blockCache.partFree -
  332.                    start->blockCache.partFree,
  333.                    end->blockCache.lru -
  334.                    start->blockCache.lru);
  335.     if (end->alloc.blocksAllocated > 0) {
  336.     fprintf(stream, "Disk blocks alloc %d free %d search %d/%d hash %d\n",
  337.                    end->alloc.blocksAllocated -
  338.                    start->alloc.blocksAllocated,
  339.                    end->alloc.blocksFreed -
  340.                    start->alloc.blocksFreed,
  341.                    end->alloc.cylsSearched -
  342.                    start->alloc.cylsSearched,
  343.                    end->alloc.cylBitmapSearches -
  344.                    start->alloc.cylBitmapSearches,
  345.                    end->alloc.cylHashes -
  346.                    start->alloc.cylHashes);
  347.     fprintf(stream, "Fragments alloc %d free %d upgrade %d blocks made %d used %d, bad hints %d\n",
  348.                    end->alloc.fragsAllocated -
  349.                    start->alloc.fragsAllocated,
  350.                    end->alloc.fragsFreed -
  351.                    start->alloc.fragsFreed,
  352.                    end->alloc.fragUpgrades -
  353.                    start->alloc.fragUpgrades,
  354.                    end->alloc.fragToBlock -
  355.                    start->alloc.fragToBlock,
  356.                    end->alloc.fullBlockFrags -
  357.                    start->alloc.fullBlockFrags,
  358.                    end->alloc.badFragList -
  359.                    start->alloc.badFragList);
  360.     }
  361.     if (end->nameCache.accesses > 0) {
  362.     fprintf(stream, "Name cache entries %d accesses %d hits %d replaced %d\n",
  363.                end->nameCache.size,
  364.                end->nameCache.accesses -
  365.                start->nameCache.accesses,
  366.                end->nameCache.hits -
  367.                start->nameCache.hits,
  368.                end->nameCache.replacements -
  369.                start->nameCache.replacements);
  370.     }
  371.     fprintf(stream, "Handles %d created %d installed %d hits %d old %d version %d flush %d\n",
  372.                end->handle.exists,
  373.                end->handle.created -
  374.                start->handle.created,
  375.                end->handle.installCalls -
  376.                start->handle.installCalls,
  377.                end->handle.installHits -
  378.                start->handle.installHits,
  379.                0,
  380.                end->handle.versionMismatch -
  381.                start->handle.versionMismatch,
  382.                end->handle.cacheFlushes -
  383.                start->handle.cacheFlushes);
  384.     fprintf(stream, "\tfetched %d hits %d released %d locks %d/%d wait %d\n",
  385.                end->handle.fetchCalls -
  386.                start->handle.fetchCalls,
  387.                end->handle.fetchHits -
  388.                start->handle.fetchHits,
  389.                end->handle.release -
  390.                start->handle.release,
  391.                end->handle.locks -
  392.                start->handle.locks,
  393.                end->handle.locks -
  394.                start->handle.locks,
  395.                end->handle.lockWaits -
  396.                start->handle.lockWaits);
  397.     fprintf(stream, "Segments fetched %d hits %d\n",
  398.                end->handle.segmentFetches -
  399.                start->handle.segmentFetches,
  400.                end->handle.segmentHits -
  401.                start->handle.segmentHits);
  402.     fprintf(stream, "Lookup relative %d absolute %d redirect %d found %d loops %d timeouts %d stale %d\n",
  403.                end->prefix.relative -
  404.                start->prefix.relative,
  405.                end->prefix.absolute -
  406.                start->prefix.absolute,
  407.                end->prefix.redirects -
  408.                start->prefix.redirects,
  409.                end->prefix.found -
  410.                start->prefix.found,
  411.                end->prefix.loops -
  412.                start->prefix.loops,
  413.                end->prefix.timeouts -
  414.                start->prefix.timeouts,
  415.                end->prefix.stale -
  416.                start->prefix.stale);
  417. }
  418.  
  419.  
  420. /*
  421.  *----------------------------------------------------------------------
  422.  *
  423.  * PrintVmStats --
  424.  *
  425.  *    Print out VM statistics.  If both a start and end
  426.  *    sample of the statistics are given then the differences between
  427.  *    the two are printed.  To just print the total cumulative statistics
  428.  *    from one sample, specify a single VmStats buffer with the 'end'
  429.  *    parameter.
  430.  *
  431.  * Results:
  432.  *    None.
  433.  *
  434.  * Side effects:
  435.  *    Prints to the specified stream
  436.  *
  437.  *----------------------------------------------------------------------
  438.  */
  439. void
  440. PrintVmStats(stream, start, end)
  441.     FILE *stream;    /* Output stream */
  442.     Vm_Stat *start;    /* 0, or address of "before run" statistics */
  443.     Vm_Stat *end;    /* End of run statistics */
  444. {
  445.     register    int    *diffPtr;
  446.     register    int    *startPtr;
  447.     register    int    *endPtr;
  448.     int            i;
  449.     int            inusePages;
  450.     int            totPages;
  451.     int            numModifiedPages;
  452.     Vm_Stat        diffStat;
  453.     int            totPercent;
  454.     int            totFaults;
  455.     int            heapPercent;
  456.     int            stkPercent;
  457.     int            quickPercent;    
  458.     int            totHits;
  459.     int            totPrefetches;
  460.     int            hitPct;
  461.  
  462.     startPtr = (int *)start;
  463.     endPtr = (int *)end;
  464.     diffPtr = (int *)&diffStat;
  465.  
  466.     for (i = 0; 
  467.          i < sizeof(Vm_Stat) / sizeof(int); 
  468.      i++, startPtr++, endPtr++, diffPtr++) {
  469.     *diffPtr = *endPtr - *startPtr;
  470.     }
  471.  
  472.     (void)Vm_Cmd(VM_COUNT_DIRTY_PAGES, &numModifiedPages);
  473.     fprintf(stream, "Kernel VM Pages: %d (Code+Data=%d Stacks=%d)\n",
  474.          end->kernMemPages + end->kernStackPages,
  475.          end->kernMemPages, end->kernStackPages);
  476.     inusePages = end->numDirtyPages + end->numUserPages;
  477.     totPages = end->numFreePages + inusePages;
  478.     fprintf(stream, "User VM Pages:   %d (Free=%d Dirty=%d Res=%d Alloc-list=%d)\n",
  479.         end->numFreePages + end->numDirtyPages + 
  480.         end->numReservePages + end->numUserPages, 
  481.         end->numFreePages, end->numDirtyPages,
  482.         end->numReservePages,
  483.         end->numUserPages);
  484.     fprintf(stream, "Modified pages: Total=%d %%Tot-dirty=%0.2f %%Inuse-dirty=%0.2f\n",
  485.         numModifiedPages,
  486.         (float) (numModifiedPages) / (float)totPages * 100.0,
  487.         (float) (numModifiedPages) / (float)inusePages * 100.0);
  488.     fprintf(stream, "FS Pages: Current=%d Max=%d Min=%d\n", 
  489.         end->fsMap - end->fsUnmap, end->maxFSPages, end->minFSPages);
  490.     fprintf(stream,
  491.          "Faults: %8d (Zero=%d FS=%d Swap=%d Quick=%d Coll=%d)\n", 
  492.          diffStat.totalFaults, diffStat.zeroFilled, diffStat.fsFilled,
  493.          diffStat.psFilled,diffStat.quickFaults, diffStat.collFaults);
  494.     fprintf(stream, "        %8d (Code=%d Heap=%d Stack=%d)\n", 
  495.          diffStat.totalFaults, diffStat.codeFaults, diffStat.heapFaults,
  496.          diffStat.stackFaults);
  497.     fprintf(stream, 
  498.         "Mod page stats:  Pot-mod=%d Not-mod=%d Not-hard-mod=%d\n",
  499.         diffStat.potModPages, diffStat.notModPages, 
  500.         diffStat.notHardModPages);
  501.  
  502.     /*
  503.      * Copy on write. 
  504.      */
  505.     totPages = diffStat.numCOWStkPages + diffStat.numCOWHeapPages;
  506.     totFaults = diffStat.numCOWStkFaults + diffStat.numCOWHeapFaults;
  507.     if (diffStat.numCOWHeapPages > 0) {
  508.     heapPercent = 100.0 * ((float)diffStat.numCOWHeapFaults / 
  509.                       diffStat.numCOWHeapPages);
  510.     } else {
  511.     heapPercent = 0;
  512.     }
  513.     if (diffStat.numCOWStkPages > 0) {
  514.     stkPercent = 100.0 * ((float)diffStat.numCOWStkFaults / 
  515.                       diffStat.numCOWStkPages);
  516.     } else {
  517.     stkPercent = 0;
  518.     }
  519.     if (totPages > 0) {
  520.     totPercent = 100.0 * ((float)totFaults / totPages);
  521.     } else {
  522.     totPercent = 0;
  523.     }
  524.     if (totFaults > 0) {
  525.     quickPercent = 100.0 * ((float)diffStat.quickCOWFaults / totFaults);
  526.     } else {
  527.     quickPercent = 0;
  528.     }
  529.     fprintf(stream, 
  530.         "COW: Heap (%d/%d)=%d%% Stk (%d/%d)=%d%% Tot (%d/%d)=%d%%\n",
  531.         diffStat.numCOWHeapFaults, diffStat.numCOWHeapPages, heapPercent,
  532.         diffStat.numCOWStkFaults, diffStat.numCOWStkPages, stkPercent,
  533.         totFaults, totPages, totPercent);
  534.     fprintf(stream, "     Quick (%d/%d)=%d%%\n",
  535.         diffStat.quickCOWFaults, totFaults, quickPercent);
  536.     /*
  537.      * Copy on reference.
  538.      */
  539.     totPages = diffStat.numCORStkPages + diffStat.numCORHeapPages;
  540.     totFaults = diffStat.numCORStkFaults + diffStat.numCORHeapFaults;
  541.     if (diffStat.numCORHeapPages > 0) {
  542.     heapPercent = 100.0 * ((float)diffStat.numCORHeapFaults / 
  543.                       diffStat.numCORHeapPages);
  544.     } else {
  545.     heapPercent = 0;
  546.     }
  547.     if (diffStat.numCORStkPages > 0) {
  548.     stkPercent = 100.0 * ((float)diffStat.numCORStkFaults / 
  549.                       diffStat.numCORStkPages);
  550.     } else {
  551.     stkPercent = 0;
  552.     }
  553.     if (totPages > 0) {
  554.     totPercent = 100.0 * ((float)totFaults / totPages);
  555.     } else {
  556.     totPercent = 0;
  557.     }
  558.     fprintf(stream,
  559.             "COR: Heap (%d/%d)=%d%% Stk (%d/%d)=%d%% Tot (%d/%d)=%d%%\n",
  560.         diffStat.numCORHeapFaults, diffStat.numCORHeapPages, heapPercent,
  561.         diffStat.numCORStkFaults, diffStat.numCORStkPages, stkPercent,
  562.         totFaults, totPages, totPercent);
  563.     totPages = diffStat.numCORStkFaults + diffStat.numCORHeapFaults;
  564.     totFaults = diffStat.numCORCOWStkFaults + diffStat.numCORCOWHeapFaults;
  565.     if (diffStat.numCORCOWHeapFaults > 0) {
  566.     heapPercent = 100.0 * ((float)diffStat.numCORCOWHeapFaults / 
  567.                       diffStat.numCORHeapFaults);
  568.     } else {
  569.     heapPercent = 0;
  570.     }
  571.     if (diffStat.numCORCOWStkFaults > 0) {
  572.     stkPercent = 100.0 * ((float)diffStat.numCORCOWStkFaults / 
  573.                       diffStat.numCORStkFaults);
  574.     } else {
  575.     stkPercent = 0;
  576.     }
  577.     if (totPages > 0) {
  578.     totPercent = 100.0 * ((float)totFaults / totPages);
  579.     } else {
  580.     totPercent = 0;
  581.     }
  582.     fprintf(stream,
  583.             "COR-mod: Heap(%d/%d)=%d%% Stk (%d/%d)=%d%% Tot (%d/%d)=%d%%\n",
  584.         diffStat.numCORCOWHeapFaults, diffStat.numCORHeapFaults,heapPercent,
  585.         diffStat.numCORCOWStkFaults, diffStat.numCORStkFaults, stkPercent,
  586.         diffStat.numCORCOWHeapFaults + diffStat.numCORCOWStkFaults,
  587.         diffStat.numCORHeapFaults + diffStat.numCORStkFaults, totPercent);
  588.  
  589.     fprintf(stream, "Swap pages copied: %d\n", diffStat.swapPagesCopied);
  590.     fprintf(stream,
  591.              "Vm allocs: %d (Free=%d From-FS=%d From-alloc-list=%d)\n",
  592.          diffStat.numAllocs, diffStat.gotFreePage, diffStat.gotPageFromFS, 
  593.          diffStat.pageAllocs);
  594.     fprintf(stream, 
  595.          "VM-FS stats: Asked=%d Free-pages=%d Allocs=%d Frees=%d\n",
  596.          diffStat.fsAsked, diffStat.haveFreePage, diffStat.fsMap, 
  597.          diffStat.fsUnmap);
  598.     fprintf(stream, "Alloc-list searches: %d (Free=%d In-use=%d)\n",
  599.          diffStat.numListSearches, diffStat.usedFreePage, 
  600.          diffStat.numListSearches - diffStat.usedFreePage);
  601.     fprintf(stream, "Extra-searches: %d (Lock=%d Ref=%d Dirty=%d)\n",
  602.          diffStat.lockSearched + diffStat.refSearched + 
  603.          diffStat.dirtySearched,
  604.          diffStat.lockSearched, diffStat.refSearched, 
  605.          diffStat.dirtySearched);
  606.     fprintf(stream, "Pages written %d\n", diffStat.pagesWritten);
  607.  
  608.     totPrefetches = diffStat.codePrefetches + diffStat.heapFSPrefetches +
  609.             diffStat.heapSwapPrefetches + diffStat.stackPrefetches;
  610.     if (totPrefetches > 0) {
  611.     totHits = diffStat.codePrefetchHits + diffStat.heapFSPrefetchHits +
  612.           diffStat.heapSwapPrefetchHits + diffStat.stackPrefetchHits;
  613.     fprintf(stream, "Prefetch stats:\n");
  614.     if (diffStat.codePrefetches > 0) {
  615.         hitPct = 100 * ((float)diffStat.codePrefetchHits / 
  616.                 (float)diffStat.codePrefetches);
  617.         fprintf(stream, "    code (%d/%d)=%d%%\n",
  618.             diffStat.codePrefetchHits, diffStat.codePrefetches, hitPct);
  619.     }
  620.     if (diffStat.heapFSPrefetches > 0) {
  621.         hitPct = 100 * ((float)diffStat.heapFSPrefetchHits / 
  622.                 (float)diffStat.heapFSPrefetches);
  623.         fprintf(stream, "    heap-fs (%d/%d)=%d%%\n",
  624.         diffStat.heapFSPrefetchHits, diffStat.heapFSPrefetches, hitPct);
  625.     }
  626.     if (diffStat.heapSwapPrefetches > 0) {
  627.         hitPct = 100 * ((float)diffStat.heapSwapPrefetchHits / 
  628.                 (float)diffStat.heapSwapPrefetches);
  629.         fprintf(stream, "    heap-swp (%d/%d)=%d%%\n",
  630.         diffStat.heapSwapPrefetchHits, diffStat.heapSwapPrefetches, 
  631.         hitPct);
  632.     }
  633.     if (diffStat.stackPrefetches > 0) {
  634.         hitPct = 100 * ((float)diffStat.stackPrefetchHits / 
  635.                 (float)diffStat.stackPrefetches);
  636.         fprintf(stream, "    stack (%d/%d)=%d%%\n",
  637.         diffStat.stackPrefetchHits, diffStat.stackPrefetches, hitPct);
  638.     }
  639.     hitPct = 100 * ((float)totHits / (float)totPrefetches);
  640.     fprintf(stream, "    total (%d/%d)=%d%%\n",
  641.         totHits, totPrefetches, hitPct);
  642.     fprintf(stream, "    aborts=   %d\n", diffStat.prefetchAborts);
  643.     }
  644. }
  645.